package org.dtrd.modules.achievement.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.dtrd.modules.achievement.entity.bean.PatientSigninPlan;
import org.dtrd.modules.achievement.entity.bean.SigninTemplateContent;
import org.dtrd.modules.achievement.entity.bean.SigninTemplateListInfo;
import org.dtrd.modules.achievement.entity.po.DtrdEntRdSigninPlan;
import org.dtrd.modules.achievement.entity.po.DtrdEntRdSigninTemplate;
import org.dtrd.modules.achievement.entity.request.SigninTemplateListRequest;
import org.dtrd.modules.achievement.entity.request.SigninTemplatePageRequest;
import org.dtrd.modules.achievement.mapper.DtrdEntRdSigninTemplateMapper;
import org.dtrd.modules.achievement.service.IDtrdEntRdSigninPlanService;
import org.dtrd.modules.achievement.service.IDtrdEntRdSigninTemplateService;
import org.dtrd.modules.system.service.ISysUserService;
import org.dtrd.modules.util.ShiroUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 打卡计划模板 服务实现类
 * </p>
 *
 * @author QR
 * @since 2022-01-04
 */
@DS("multi-datasource1")
@Service
@Slf4j
public class DtrdEntRdSigninTemplateServiceImpl extends ServiceImpl<DtrdEntRdSigninTemplateMapper, DtrdEntRdSigninTemplate> implements IDtrdEntRdSigninTemplateService {

    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IDtrdEntRdSigninPlanService signInPlanService;

    @Override
    public List<SigninTemplateListInfo> getSigninTemplateList(SigninTemplateListRequest request) {
        LambdaQueryWrapper<DtrdEntRdSigninTemplate> queryWrapper = baseQueryWrapper()
                .eq(StringUtils.isNotBlank(request.getOrgCode()),
                        DtrdEntRdSigninTemplate::getOrgCode,request.getOrgCode())
                .notIn(DtrdEntRdSigninTemplate::getDataId, 0)
                .orderByDesc(DtrdEntRdSigninTemplate::getUpdateTime);
        List<DtrdEntRdSigninTemplate> poList = list(queryWrapper);
        List<SigninTemplateListInfo> dtoList = new ArrayList<>(poList.size());
        if (!poList.isEmpty()) {
            dtoList = poList.stream().map(po -> {
                SigninTemplateListInfo signinTemplateListInfo = new SigninTemplateListInfo(po);
                if (StrUtil.isNotBlank(po.getUpdateBy())) {
                    signinTemplateListInfo.setEditor(sysUserService.getRealNameByUserName(po.getUpdateBy()));
                }
                return signinTemplateListInfo;
            }).collect(Collectors.toList());
        }
        return dtoList;
    }

    @Override
    public IPage<SigninTemplateListInfo> pageSigninTemplate(SigninTemplatePageRequest request) {
        LambdaQueryWrapper<DtrdEntRdSigninTemplate> queryWrapper = baseQueryWrapper();
        IPage<DtrdEntRdSigninTemplate> page = new Page<>(request.getPageNum(), request.getPageSize());
        if (StrUtil.isNotBlank(request.getOrgCode())) {
            queryWrapper.eq(DtrdEntRdSigninTemplate::getOrgCode, request.getOrgCode());
        }
        page = page(page, queryWrapper);
        return page.convert(po -> {
            SigninTemplateListInfo signinTemplateListInfo = new SigninTemplateListInfo(po);
            if (StrUtil.isNotBlank(po.getUpdateBy())) {
                signinTemplateListInfo.setEditor(sysUserService.getRealNameByUserName(po.getUpdateBy()));
            }
            return signinTemplateListInfo;
        });
    }

    @Override
    public SigninTemplateContent getSigninTemplate(Integer dataId) {
        DtrdEntRdSigninTemplate dtrdEntRdSigninTemplate = getById(dataId);
        return Optional.ofNullable(dtrdEntRdSigninTemplate)
                .map(po -> {
                    SigninTemplateContent dto = new SigninTemplateContent().parseFromPo(po);
                    // 初始模版的名字和id设置为空
                    if (po.getDataId() == 0 || po.getDataId() == null) {
                        dto.setSignInName(null);
                        dto.setDataId(null);
                    }
                    return dto;
                })
                .orElse(null);
    }

    @Override
    public String getTemplateNameById(Integer templateId) {
        DtrdEntRdSigninTemplate template = getById(templateId);
        if (template != null) {
            log.info("DtrdEntRdSigninTemplateServiceImpl.getTemplateNameById.[templateId] temnplkate=" + template.getDataId() + "; name=" + template.getSignInName());
        }

        return Optional.ofNullable(template).map(DtrdEntRdSigninTemplate::getSignInName).orElse(null);
    }

    @Override
    public boolean hasRelatePatient(Integer templateId) {
        List<DtrdEntRdSigninPlan> planList = signInPlanService.list(Wrappers.lambdaQuery(DtrdEntRdSigninPlan.class)
                .eq(DtrdEntRdSigninPlan::getSignInTemplateId, templateId));
        return CollectionUtil.isNotEmpty(planList);
    }

    @Override
    public boolean hasSameTemplateName(Integer templateId, String templateName, String orgCode) {
        LambdaQueryWrapper<DtrdEntRdSigninTemplate> wrapper = Wrappers.lambdaQuery(DtrdEntRdSigninTemplate.class)
                .eq(DtrdEntRdSigninTemplate::getOrgCode, orgCode)
                .eq(DtrdEntRdSigninTemplate::getSignInName, templateName);
        DtrdEntRdSigninTemplate queryTemplate = getOne(wrapper);
        return queryTemplate != null && !Objects.equals(queryTemplate.getDataId(), templateId);
    }

    @Override
    public boolean saveOrUpdateSigninTemplate(SigninTemplateContent dto) {
        DtrdEntRdSigninTemplate po = new DtrdEntRdSigninTemplate();
        String userName = ShiroUtil.getUserName();
        if (dto.getDataId() == null) {
            po = po.init();
            po.setCreateBy(userName);
        }
        po.parseFromDTO(dto);
        po.setUpdateBy(userName);
        return saveOrUpdate(po);
    }

    @Override
    public boolean removeSigninTemplate(Integer dataId) {
        return removeById(dataId);
    }

    @Override
    public String getTemplateNameByServiceInfo(Integer patientId, Date startTime, Date endTime) {
        return baseMapper.getTemplateNameByServiceInfo(patientId, startTime, endTime);
    }

    @Override
    public String getTemplateNameByPatientId(Integer patientId) {
        PatientSigninPlan signinPlan = signInPlanService.getSigninPlan(patientId);
        return Optional.ofNullable(signinPlan).map(PatientSigninPlan::getSignInTemplateName).orElse(null);
    }

    private LambdaQueryWrapper<DtrdEntRdSigninTemplate> baseQueryWrapper() {
        return Wrappers.lambdaQuery(DtrdEntRdSigninTemplate.class)
                .eq(DtrdEntRdSigninTemplate::getIsDel, 0);
    }

    private LambdaUpdateWrapper<DtrdEntRdSigninTemplate> baseUpdateWrapper() {
        return Wrappers.lambdaUpdate(DtrdEntRdSigninTemplate.class)
                .eq(DtrdEntRdSigninTemplate::getIsDel, 0);
    }
}
